home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / a_utils / perl / mac-perl / mcprl402.bin / Perl_src / macperl.c / macperl.c
Encoding:
C/C++ Source or Header  |  1993-01-25  |  8.1 KB  |  393 lines  |  [TEXT/MPS ]

  1. /*********************************************************************
  2. File        :    macperl.c    - Mac specific extensions
  3. Author    :    Matthias Neeracher & Tim Endres
  4. Started    :    28May91                                Language    :    MPW C
  5. Last        :    17Jan93
  6.  
  7. Copyright (c) 1991-93 Matthias Neeracher & Tim Endres
  8. *********************************************************************/
  9.  
  10. #include <Types.h>
  11. #include <Resources.h>
  12. #include <QuickDraw.h>
  13. #include <Fonts.h>
  14. #include <Menus.h>
  15. #include <TextEdit.h>
  16. #include <Dialogs.h>
  17. #include <SegLoad.h>
  18. #include <StandardFile.h>
  19. #include <Lists.h>
  20. #include <Files.h>
  21. #include <Memory.h>
  22. #include <TFileSpec.h>
  23.  
  24. /* Ugly hack since QuickDraw defines another invert */
  25. #define RESOLVE_MAC_CONFLICTS
  26.  
  27. #include "EXTERN.h"
  28. #include "perl.h"
  29.  
  30. void InitToolbox()
  31. {
  32.     InitGraf((Ptr) &qd.thePort);
  33.     InitFonts();
  34.     InitWindows();
  35.     InitMenus();
  36.     TEInit();
  37.     InitDialogs(nil);
  38.     InitCursor();
  39. }
  40.  
  41. static void CenterWindow(DialogPtr dlg)
  42. {
  43.     Rect    *        screen;
  44.     short            hPos;
  45.     short            vPos;
  46.     
  47.     screen    =    &qd.screenBits.bounds;
  48.     hPos    =    screen->right+screen->left-dlg->portRect.right >> 1;
  49.     vPos    =    (screen->bottom-screen->top-dlg->portRect.bottom)/3;
  50.     vPos    +=    screen->top;
  51.     MoveWindow(dlg, hPos, vPos, true);
  52. }    
  53.  
  54. static ControlHandle GetDlgCtrl(DialogPtr dlg, short item)
  55. {
  56.     short     kind;
  57.     Handle    hdl;
  58.     Rect    box;
  59.     
  60.     GetDItem(dlg, item, &kind, &hdl, &box);
  61.     return (ControlHandle) hdl;
  62. }
  63.  
  64. static void GetDlgText(DialogPtr dlg, short item, char * text)
  65. {
  66.     getitext((Handle) GetDlgCtrl(dlg, item), text);
  67. }
  68.  
  69. static void SetDlgText(DialogPtr dlg, short item, char * text)
  70. {
  71.     setitext((Handle) GetDlgCtrl(dlg, item), text);
  72. }
  73.  
  74. static void GetDlgRect(DialogPtr dlg, short item, Rect * r)
  75. {
  76.     short     kind;
  77.     Handle    hdl;
  78.     
  79.     GetDItem(dlg, item, &kind, &hdl, r);
  80. }
  81.  
  82. static void FrameDlgRect(DialogPtr dlg, short item)
  83. {
  84.     Rect    r;
  85.     
  86.     GetDlgRect(dlg, item, &r);
  87.     InsetRect(&r, -4, -4);
  88.     PenSize(3, 3);
  89.     FrameRoundRect(&r, 16, 16);
  90.     PenSize(1,1);
  91. }
  92.  
  93. #define TempPStr(cstr)    ((StringPtr) memcpy(tmpPStr+1, cstr, *tmpPStr = strlen(cstr)), tmpPStr)
  94.  
  95. double
  96. do_answer(arglast)
  97.     int *arglast;
  98. {
  99.     register STR **st = stack->ary_array;
  100.     register int sp = arglast[0];
  101.     int            maxarg = arglast[2] - sp;
  102.     char *        prompt;
  103.     short        item;
  104.     DialogPtr    dlg;
  105.     Str255        tmpPStr;
  106.  
  107.     if (maxarg > 4)
  108.         fatal("answer() called with more than 4 arguments");
  109.         
  110.     prompt = (char*)str_get(st[++sp]);
  111.  
  112.     dlg = GetNewDialog((maxarg>1) ? 1999+maxarg : 2001, NULL, (WindowPtr)-1);
  113.     InitCursor();
  114.     SetDlgText(dlg, 5, prompt);
  115.     
  116.     if (maxarg>1) 
  117.         for (item = 1; item<maxarg; ++item) {
  118.             prompt = (char*)str_get(st[++sp]);
  119.             memcpy(tmpPStr+1, prompt, *tmpPStr = st[sp]->str_cur);
  120.             SetCTitle(GetDlgCtrl(dlg, item), tmpPStr);
  121.         }
  122.     else
  123.         SetCTitle(GetDlgCtrl(dlg, 1), "\pOK");
  124.     
  125.     CenterWindow(dlg);
  126.     ShowWindow(dlg);
  127.     SetPort(dlg);
  128.     FrameDlgRect(dlg, ok);
  129.     ModalDialog((ModalFilterProcPtr)0, &item);
  130.     DisposDialog(dlg);
  131.     
  132.     return (maxarg>1) ? maxarg-item-1 : 0;
  133. }
  134.  
  135. static char     string_reply[256];
  136.  
  137. STR * do_ask(arglast, maxarg)
  138.     int *arglast;
  139.     int maxarg;
  140. {
  141.     register STR **st = stack->ary_array;
  142.     register int sp = arglast[0];
  143.     char *        prompt;
  144.     short        item;
  145.     DialogPtr    dlg;
  146.     STR *         str;
  147.  
  148.     if (maxarg > 2)
  149.         fatal("ask() called with more than 2 arguments");
  150.         
  151.     prompt = (char*)str_get(st[++sp]);
  152.  
  153.     dlg = GetNewDialog(2010, NULL, (WindowPtr)-1);
  154.     InitCursor();
  155.     SetDlgText(dlg, 3, prompt);
  156.     
  157.     if (maxarg == 2)
  158.         SetDlgText(dlg, 4, (char*)str_get(st[++sp]));
  159.     SelIText(dlg, 4, 0, 1024);
  160.  
  161.     InitCursor();
  162.     CenterWindow(dlg);
  163.     ShowWindow(dlg);
  164.     SetPort(dlg);
  165.     FrameDlgRect(dlg, ok);
  166.     ModalDialog((ModalFilterProcPtr)0, &item);
  167.     switch (item) {
  168.     case ok:
  169.         str = str_2mortal(Str_new(22,257));
  170.         str->str_cur = 256;
  171.            str->str_pok = 1;
  172.         GetDlgText(dlg, 4, (StringPtr) str->str_ptr);
  173.         str->str_cur = strlen(str->str_ptr);
  174.         break;
  175.     case cancel:
  176.         break;
  177.     }
  178.     DisposDialog(dlg);
  179.     
  180.     return (item == ok) ? str : &str_undef;
  181. }
  182.  
  183. static ListHandle picklist = NULL;
  184.  
  185. #define SetCell(cell, row, column)    { (cell).h = column; (cell).v = row; }
  186. #define ROW(cell)                     (cell).v
  187.  
  188. pascal void
  189. MacListUpdate(myDialog, myItem)
  190. DialogPtr        myDialog;
  191. short            myItem;
  192. {
  193. Rect            myrect;
  194. #pragma unused (myItem)
  195.  
  196.     LUpdate(myDialog->visRgn, picklist);
  197.     myrect = (**(picklist)).rView;
  198.     InsetRect(&myrect, -1, -1);
  199.     FrameRect(&myrect);
  200.     }
  201.  
  202. pascal Boolean
  203. MacListFilter(myDialog, myEvent, myItem)
  204. DialogPtr        myDialog;
  205. EventRecord        *myEvent;
  206. short            *myItem;
  207. {
  208. Rect    listrect;
  209. short    myascii;
  210. Handle    myhandle;
  211. Point    mypoint;
  212. short    mytype;
  213. int        activate;
  214.  
  215.     SetPort(myDialog);
  216.     if (myEvent->what == keyDown) {
  217.         myascii = myEvent->message % 256;
  218.         if (myascii == '\015' || myascii == '\003') {    /* This is return or enter... */
  219.             *myItem = 1;
  220.             return true;
  221.             }
  222.         }
  223.     else if (myEvent->what == mouseDown) {
  224.         mypoint = myEvent->where;
  225.         GlobalToLocal(&mypoint);
  226.         GetDItem(myDialog, 4, &mytype, &myhandle, &listrect);
  227.         if (PtInRect(mypoint, &listrect) && picklist != NULL) {
  228.             if (LClick(mypoint, (short)myEvent->modifiers, picklist)) {
  229.                 /* User double-clicked in cell... */
  230.                 *myItem = 1;
  231.                 return true;
  232.                 }
  233.             }
  234.         }
  235.     else if (myEvent->what == activateEvt && picklist != NULL) {
  236.         activate = (myEvent->modifiers & 0x01) != 0;
  237.         LActivate((Boolean) activate, picklist);
  238.         }
  239.     
  240.     return false;
  241.     }
  242.  
  243. STR *
  244. do_pick(arglast)
  245.     int *arglast;
  246. {
  247.     register STR **st = stack->ary_array;
  248.     register int sp = arglast[0];
  249.     int            maxarg = arglast[2] - sp - 1;
  250.     char *        prompt;
  251.     short        itemHit;
  252.     Boolean        done;
  253.     DialogPtr    dlg;
  254.     ListHandle    mylist;
  255.     Cell        mycell;
  256.     short        mytype;
  257.     Handle        myhandle;
  258.     Point        cellsize;
  259.     Rect        listrect, dbounds;
  260.     char    *    item;
  261.  
  262.     prompt = (char*)str_get(st[++sp]);
  263.     InitCursor();
  264.     dlg = GetNewDialog(2020, NULL, (WindowPtr)-1);
  265.     
  266.     SetDlgText(dlg, 3, prompt);
  267.     GetDItem(dlg, 4, &mytype, &myhandle, &listrect);
  268.     SetDItem(dlg, 4, mytype, (Handle)MacListUpdate, &listrect);
  269.     
  270.     SetPort(dlg);
  271.     InsetRect(&listrect, 1, 1);
  272.     SetRect(&dbounds, 0, 0, 1, maxarg);
  273.     cellsize.h = (listrect.right - listrect.left);
  274.     cellsize.v = 17;
  275.  
  276.     listrect.right -= 15;
  277.  
  278.     picklist = LNew(&listrect, &dbounds, cellsize, 0,
  279.                             dlg, true, false, false, true);
  280.  
  281.     mylist = picklist;
  282.     LDoDraw(false, mylist);
  283.     
  284.     SetCell(mycell, 0, 0);
  285.     for (; mycell.v<maxarg; ++mycell.v)    {
  286.         item = str_get(st[++sp]);
  287.         LSetCell(item, st[sp]->str_cur, mycell, mylist);
  288.     }
  289.  
  290.     LDoDraw(true, mylist);
  291.     CenterWindow(dlg);
  292.     ShowWindow(dlg);
  293.     
  294.     for (done=false; !done; ) {
  295.         SetPort(dlg);
  296.         FrameDlgRect(dlg, ok);
  297.         ModalDialog(MacListFilter, &itemHit);
  298.         switch (itemHit) {
  299.         case ok:
  300.             SetCell(mycell, 0, 0);
  301.             done = true;
  302.             if (!LGetSelect(true, &mycell, picklist))
  303.                 itemHit = cancel;
  304.             break;
  305.         case cancel:
  306.             done = true;
  307.             break;
  308.         }
  309.     }    /* Modal Loop */
  310.  
  311.     SetPort(dlg);
  312.     
  313.     LDispose(mylist);
  314.     picklist = NULL;
  315.     DisposDialog(dlg);
  316.     
  317.     if (itemHit == ok)
  318.         return str_smake(st[arglast[0]+mycell.v+2]);
  319.     else
  320.         return &str_undef;    
  321. }
  322.  
  323. void GetProgFile(int * outCnt, FSSpec * desc)
  324. {
  325.     short        message;
  326.     short        count;
  327.     FCBPBRec    fcb;
  328.     CInfoPBRec    info;
  329.     
  330.     fcb.ioNamePtr    =    &desc->name;
  331.     fcb.ioRefNum    =    CurResFile();
  332.     fcb.ioFCBIndx    =    0;
  333.     
  334.     if (PBGetFCBInfoSync(&fcb))
  335.         fatal("MacPerl can't find its own resource fork.\n");
  336.     
  337.     desc->vRefNum    =    fcb.ioFCBVRefNum;
  338.     desc->parID        =    fcb.ioFCBParID;
  339.     
  340.     if (FSpCatInfo(desc, &info))
  341.         fatal("MacPerl can't find itself.\n");
  342.     
  343.     if (info.hFileInfo.ioFlLgLen) {
  344.         desc[1] = desc[0];
  345.         *outCnt = 2;                            /* Use data fork */
  346.     } else
  347.         *outCnt = 1;
  348.     
  349.     desc += *outCnt;
  350.     
  351.     CountAppFiles(&message, &count);
  352.     
  353.     if (count) {
  354.         int        i;
  355.         AppFile    arg;
  356.         
  357.         for (i=0; i++<count; ) {
  358.             GetAppFiles(i, &arg);
  359.             
  360.             if (!(*outCnt)++) {
  361.                 if (count>1)
  362.                     warn("I picked \"%P\" as your script.\n", arg.fName);
  363.                 if (arg.fType != 'TEXT')
  364.                     fatal("MacPerl can't do anything with a non-text script.\n");
  365.             }
  366.             
  367.             WD2FSSpec(arg.vRefNum, arg.fName, desc++);
  368.             
  369.             if (*outCnt == 100) {
  370.                 warn("MacPerl ignored all files after the first 100.\n");
  371.                 
  372.                 break;
  373.             }
  374.         } 
  375.     } else if (*outCnt == 1) {
  376.         Point     wh;
  377.         SFTypeList    types;
  378.         SFReply    reply;
  379.         
  380.         wh.h = wh.v = 75;
  381.         types[0]    = 'TEXT';
  382.         
  383.         SFGetFile(wh, "", (FileFilterProcPtr) nil, 1, types, (DlgHookProcPtr) nil, &reply);
  384.  
  385.         if (!reply.good)
  386.             fatal("MacPerl needs a program file to run.\n");
  387.     
  388.         WD2FSSpec(reply.vRefNum, reply.fName, desc);
  389.         
  390.         ++*outCnt;
  391.     }
  392. }
  393.